/**
 * @file 文件流相关api
 */

import { isEmpty } from '../core/types'

/**
 * 获取 不带后缀的文件名
 * @param {string} fileName 文件全名
 * @returns {string} 文件名（不带后缀）
 */
export const getFileName = (fileName: string): string => {
  if (isEmpty(fileName)) {
    return ''
  }

  const index = fileName.lastIndexOf('.')
  if (index > -1) {
    return fileName.substring(0, index)
  }
  return fileName
}

/**
 * 获取 文件的后缀名
 * @param {string} fileName 文件全名
 * @returns {string} 文件后缀名
 */
export const getFileSuffix = (fileName: string): string => {
  if (isEmpty(fileName)) {
    return ''
  }

  const index = fileName.lastIndexOf('.')
  if (index > -1) {
    return fileName.substring(index + 1)
  }
  return ''
}

/**
 * 获取格式化后的文件大小
 * @param {number} size 文件大小（字节数）
 * @returns {string} 格式化后的字符
 */
export const formatFileSize = (size: string | number) => {
  if (isEmpty(size) || Number(size) === 0) {
    return '0kb'
  }

  const unitArray = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  let index = 0

  const srcsize = parseFloat(size as string)
  index = Math.floor(Math.log(srcsize) / Math.log(1024))

  const newSize = (srcsize / 1024 ** index).toFixed(2)
  return `${Number(newSize)} ${unitArray[index]}`
}

/**
 * 将 file、blob、stream 格式 转 DateURL
 * @param {Blob | File } blob
 * @returns {Promise<string | ArrayBuffer | null>}
 */
export const blobToDataURL = (blob: Blob | File) => {
  return new Promise<string | ArrayBuffer | null>((resolve, reject) => {
    let reader = new FileReader()
    reader.readAsDataURL(blob)
    reader.onload = () => {
      resolve(reader.result)
    }
    reader.onerror = err => {
      reject(err)
    }
  })
}

/**
 * 将图片的 dataURL 转为 Blob 格式
 * @param {String} dataURL
 * @returns {Blob}
 */
export const dataURLtoBlob = (dataURL: string) => {
  let arr = dataURL.split(',')
  let mime = arr[0]!.match(/:(.*?);/)![1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

/**
 * 将图片的 url 转为 base64 格式
 * @param {string} url
 * @returns {Promise<string>}
 */
export const getImgToBase64 = (url: string) => {
  return new Promise<string>((resolve, reject) => {
    let canvas: HTMLCanvasElement | null = document.createElement('canvas')
    let ctx = canvas.getContext('2d')
    let img = new Image()
    img.crossOrigin = 'Anonymous'
    img.onload = function () {
      canvas!.height = img.height
      canvas!.width = img.width
      ctx!.drawImage(img, 0, 0)
      var dataURL = canvas!.toDataURL('image/jpg')
      resolve(dataURL)
      canvas = null
    }
    img.onerror = err => reject(err)
    img.src = url
  })
}

/**
 * 将图片的 url 转为 Blob 格式
 * @param {string} url
 * @returns {Promise<Blob>}
 */
export const getImgToBlob = (url: string) => {
  return new Promise<Blob>((resolve, reject) => {
    getImgToBase64(url)
      .then(dataURL => {
        resolve(dataURLtoBlob(dataURL))
      })
      .catch(err => {
        reject(err)
      })
  })
}

/**
 * 触发文件下载 - 使用a标签
 * @param {string} fileName
 * @param {BlobPart | File} content
 * @param {string} type
 * @returns {void}
 */
export const downloadFile = (fileName: string, content: File | BlobPart, type = 'text/plain') => {
  var el = document.createElement('a')
  var blob = new Blob([content], { type })
  el.href = URL.createObjectURL(blob)
  el.download = fileName
  el.addEventListener('click', e => e.stopImmediatePropagation())
  document.body.appendChild(el)
  el.click()
  document.body.removeChild(el)
}
